﻿package com._public._ui
{
    import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
    import flash.display.Sprite;
	import flash.display.Stage;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
	import flash.geom.Point;

    /**
     * 颜色拾取器
     * @author wzh
	 * 修改：2010-8-13 11:03
     */
    public class ScColorPicker extends Sprite
    {
        private var clicker:Clicker
        private var colorArea:ColorFormArea
        public var _stage:Object
        /**
         * 最近的一次颜色值
         */
        private var lastestColor:String = "0x000000";
        public function ScColorPicker(wid:uint=20,hei:uint=20) :void
        {
            //add clicker
			Clicker.wid = wid
			Clicker.hei = hei;
			clicker = new Clicker;
			colorArea= new ColorFormArea(colorChangeHandler);
            super.addChild(clicker);
            colorArea.visible = false;
            this.addEventListener(Event.ADDED_TO_STAGE, addThis);
        }

        /**
         * 获得颜色值
         */
        public function get color():uint {
            return uint(lastestColor);
        }
        /**
         * 获得颜色值
         */
        public function set color(value:uint):void{
            lastestColor = String(value);
			clicker.color = lastestColor;
        }
        /**
         * 获得颜色字符串
         */
        public function get colorString():String {
            return lastestColor;
        }

        private function colorChangeHandler(color:String):void {
            clicker.color = color;
        }

		private function colorAreaClick(event:MouseEvent = null):void {
			if (colorArea.mouseY < 30) return
                    colorArea.visible = false;
                    sendSelectEvent();
		 }
        /**
         * 控制是否显示颜色区域
         * @param    event
         */
        private function clickThis(event:MouseEvent = null):void {
            if (colorArea.visible) {
                    colorArea.visible = false;
                    sendSelectEvent();
            }else {
				_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
              colorArea.visible = true;
				var point:Point = localToGlobal(new Point((_stage is Stage)?0:0-colorArea.width, (_stage is Stage)?0:-35));
               colorArea.x = point.x;
                if (this._stage.mouseY > _stage.height - colorArea.height) {
                    colorArea.y = point.y-colorArea.height;
                }else {
                    colorArea.y = point.y + this.height;
                }
            }
        }

        private function keyDown(event:KeyboardEvent):void {
            switch(event.keyCode) {
                case 27://Esc Key
                    showLatestColor();
                    break;
                case 13://Enter Key
                    colorArea.visible = false;
                    sendSelectEvent();
                    break;
            }
        }

        private function lostFocus(event:MouseEvent):void {
			if(_stage==null)return
            if (!colorArea.hitTestPoint(_stage.mouseX,_stage.mouseY))
            {
                showLatestColor();
            }
        }

        private function lostSystemFocus(event:Event):void {
            showLatestColor();
        }

        /**
         * 显示最近的一次颜色
         */
        private function showLatestColor():void {
            colorArea.visible = false;
            clicker.color = lastestColor;
			if(_stage)_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
        }

        private function addThis(event:Event):void {
			if (_stage == null) _stage = stage;
			this.removeEventListener(Event.ADDED_TO_STAGE, addThis);
			 _stage.addChild(colorArea);
            if(!hasEventListener(MouseEvent.CLICK))
                this.addEventListener(MouseEvent.CLICK, clickThis);
           // if(!hasEventListener(Event.REMOVED_FROM_STAGE))
              //  this.addEventListener(Event.REMOVED_FROM_STAGE, removeThis);
			colorArea.addEventListener(MouseEvent.CLICK,colorAreaClick)
            _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
            _stage.addEventListener(MouseEvent.MOUSE_DOWN, lostFocus);
			
            if(!hasEventListener(Event.DEACTIVATE))
                this.addEventListener(Event.DEACTIVATE, lostSystemFocus);
				
        }

        private function removeThis(event:Event):void {
            this.removeEventListener(MouseEvent.CLICK, clickThis);
            this.removeEventListener(Event.REMOVED_FROM_STAGE, removeThis);
            _stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
            _stage.removeEventListener(MouseEvent.MOUSE_DOWN, lostFocus);
            this.removeEventListener(Event.DEACTIVATE, lostSystemFocus);
			_stage.removeChild(colorArea)
        }

        /**
         * @eventType flash.events.Event.Select
         */
        [Event(name = "select", type = "flash.events.Event")]
        private function sendSelectEvent():void {
            lastestColor = clicker.color;
            dispatchEvent(new Event(Event.SELECT));
			_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
        }

        //disable functions
        public override function addChild(child:DisplayObject):DisplayObject
        {
            throw new Error("此方法不可用");
        }
        public override function addChildAt(child:DisplayObject, index:int):DisplayObject
        {
            throw new Error("此方法不可用");
        }
        public override function contains(child:DisplayObject):Boolean
        {
            throw new Error("此方法不可用");
        }
        public override function removeChild(child:DisplayObject):DisplayObject
        {
            throw new Error("此方法不可用");
        }
        public override function removeChildAt(index:int):DisplayObject
        {
            throw new Error("此方法不可用");
        }
        public override function setChildIndex(child:DisplayObject, index:int):void
        {
            throw new Error("此方法不可用");
        }
        public override function swapChildren(child1:DisplayObject, child2:DisplayObject):void
        {
            throw new Error("此方法不可用");
        }
        public override function swapChildrenAt(index1:int, index2:int):void
        {
            throw new Error("此方法不可用");
        }
        public override  function set width(value:Number):void
        {
            throw new Error("尝试对只读属性进行赋值");
        }
        public override  function set height(value:Number):void
        {
            throw new Error("尝试对只读属性进行赋值");
        }

    }

}


import flash.display.CapsStyle;
import flash.display.JointStyle;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BevelFilter;
import flash.filters.BitmapFilterQuality;
import flash.filters.BitmapFilterType;
import flash.text.TextField;
import flash.text.TextFieldType;
class Clicker extends Sprite {

    /**
     * 拾色器的头
     */
    private var myColorArea:ClickColorArea = new ClickColorArea;

    /**
     * 包含的颜色的字符串表示形式
     */
    private var theColor:String = "0x000000";
	public static var wid:uint = 30;
	public static var hei:uint = 20;
    public function Clicker():void {
        with(graphics){
            lineStyle(1, 0xFFFFFF, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
            moveTo(0, hei);
            lineTo(0, 0);
            lineTo(wid, 0);
            lineStyle(1, 0xAAAAAA, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
            lineTo(wid, hei);
            lineTo(0, hei);
            lineStyle(1, 0xEEEEEE, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
            moveTo(1, hei-1);
            lineTo(1, 1);
            lineTo(wid-1, 1);
            lineTo(wid-1, hei-1);
            lineTo(1, hei-1);
            lineStyle(1, 0xCCCCCC, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
            moveTo(2, hei-2);
            lineTo(2, 2);
            lineTo(wid-2, 2);
            lineStyle(1, 0xFFFFFF, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
            lineTo(wid-2, hei-2);
            lineTo(2, hei-2);
        }

        myColorArea.x = 2.5;
        myColorArea.y = 2.5;
        addChild(myColorArea);

        var blackArr:Shape = new Shape;
        blackArr.graphics.beginFill(0xEEEEEE);
        blackArr.graphics.drawRect(0, 0, 8, 6);
        blackArr.graphics.endFill();
        blackArr.graphics.beginFill(0);
        blackArr.graphics.lineStyle(.01, 0xCCCCCC, 1, true, "normal", CapsStyle.SQUARE, JointStyle.MITER);
        blackArr.graphics.moveTo(1, 1);
        blackArr.graphics.lineTo(7, 1);
        blackArr.graphics.lineTo(4, 5);
        blackArr.graphics.lineTo(1, 1);
        blackArr.graphics.endFill();
        blackArr.x = this.width - blackArr.width - 2;
        blackArr.y = this.height - blackArr.height - 2;
        addChild(blackArr);
    }

    /**
     * 改变选中的颜色
     * @param    color
     */
    public function changeColor(color:uint):void {
        myColorArea.changeColor(color);
    }

    /**
     * 设置颜色
     */
    public function set color(color:String):void {
        theColor = color;
        myColorArea.changeColor(uint(color));
    }
    /**
     * 获得颜色
     */
    public function get color():String {
        return theColor;
    }
}

class ClickColorArea extends Sprite {

    /**
     * 拾色器头显示当前颜色的部分
     * @param    color  默认为黑色
     */
    public function ClickColorArea(color:uint = 0x000000):void {
        changeColor(color);
    }

    /**
     * 改变此显示区域的颜色
     * @param    color
     */
    public function changeColor(color:uint):void {
        graphics.clear();
        graphics.beginFill(color);
        graphics.drawRect(0, 0,  Clicker.wid-5,  Clicker.hei-5);
        graphics.endFill();
    }
}

class ColorForm extends Sprite {

    private var theHandler:Function;

    /**
     * 颜色块的颜色
     */
    private var theColor:String = "";

    private var sharp:Shape = new Shape;
    public static var colorWid:uint = 10;
    /**
     * 颜色块
     * @param    color
     * @param    mouseOverHandler
     */
    public function ColorForm(color:String, mouseOverHandler:Function = null):void {
        theColor = color;
        theHandler = mouseOverHandler;

        //绘制中部
        graphics.beginFill(uint(color));
        graphics.drawRect(0, 0, colorWid, colorWid);
        graphics.endFill();
        //绘制外圈
        sharp.graphics.lineStyle(1, 0xFFFFFF);
        sharp.graphics.drawRect(0, 0, colorWid, colorWid);
        addChild(sharp);
        sharp.visible = false;

        this.addEventListener(Event.REMOVED_FROM_STAGE, removeThis);
        this.addEventListener(MouseEvent.MOUSE_OVER, mouseOverThis);
    }

    private function mouseOverThis(event:MouseEvent):void {
        if (Boolean(theHandler)) {
            theHandler(theColor,this);
        }
    }

    private function mouseOutThis(event:MouseEvent):void {
        select = false;
    }

    private function removeThis(event:Event):void {
        this.removeEventListener(Event.REMOVED_FROM_STAGE, removeThis);
        this.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverThis);
    }

    /**
     * 获得或设置选中状态
     */
    public function set select(value:Boolean):void {
        sharp.visible = value;
    }
    public function get select():Boolean {
        return sharp.visible;
    }

    /**
     * 获得本色块的颜色
     */
    public function get color():String {
        return theColor;
    }
}

class ColorFormArea extends Sprite {

    private var colorArr:Array = ["00", "33", "66", "99", "CC", "FF"];

    //color text
    private var txt:TextField = new TextField;
    /**
     * 颜色块数组
     */
    private const RECTS_ARR:Array = new Array;

    /**
     * 颜色改变时的处理函数
     */
    private var theHandler:Function;

    /**
     * 颜色块区域
     */
    private var colorRects:Sprite = new Sprite;

    /**
     * 构造一个新的ColorFormArea实例
     */
    public function ColorFormArea(colorChangeHandler:Function = null):void {
        theHandler = colorChangeHandler;
        var wid:Number=(ColorForm.colorWid+1)*18+20
		var hei:Number=(ColorForm.colorWid+1)*13+40
        var bg:Sprite = new Sprite;
        with(bg){
            graphics.beginFill(0xFFFFFF);
			graphics.lineStyle(1,0xbbbbbb)
            graphics.drawRect(0, 0, wid, hei);
            graphics.endFill();
        }
        //添加滤镜
        addChild(bg);

        //add text
        txt.width = 60;
        txt.height = 20;
		bg.graphics.lineStyle(1, 0xdddddd)
		bg.graphics.drawRect(10, 5, 60, 20)
		bg.graphics.endFill()
        txt.type = TextFieldType.INPUT;
        txt.x = 10;
        txt.y = 5;
        txt.maxChars = 7;
        txt.restrict = "0-9a-f#";
        txt.text = "0x000000";
        txt.addEventListener(Event.CHANGE, txtChange);
        addChild(txt);

        //add color rects bg
        var colorBG:Sprite = new Sprite;
        colorBG.graphics.lineStyle(1);
        colorBG.graphics.beginFill(0);
        colorBG.graphics.drawRect(0, 0, 300, 300);
        colorBG.graphics.endFill();
        addChild(colorBG);

        //add color rects
        colorRects.x = txt.x + 1;
        colorRects.y = txt.y + txt.height + 5;
        addChild(colorRects);
		var col:Array =["00","22","44","66","88","99","AA","A8","B8","BB","C8","CC","D6","DD","E6","EE","F6","FF"]
		var color:String
        for (var i:int = 0; i < 18; i++) {
            for (var j:int = 0; j < 13; j++) {
				if(j == 12) {
					color = "0x"+col[i]+col[i]+col[i]
					}else {
					color = "0x" + colorArr[Math.floor(i / 6) + Math.floor(j / 6) * 3] + colorArr[i % 6] + colorArr[j % 6];
						}
                var colorForm:ColorForm = new ColorForm(color, selectColorHandler);
                colorForm.x = i * (colorForm.width);
                colorForm.y = j * (colorForm.height);
                colorRects.addChild(colorForm);
                RECTS_ARR.push(colorForm);
            }
        }
		 RECTS_ARR.push(colorForm)
        colorBG.width = colorRects.width + 1;
        colorBG.height = colorRects.height + 1;
        colorBG.x = colorRects.x - 1;
        colorBG.y = colorRects.y - 1;

        this.addEventListener(Event.REMOVED_FROM_STAGE, removeThis);
    }

    /**
     * 移除侦听器
     * @param    event
     */
    private function removeThis(event:Event):void {
        txt.removeEventListener(Event.CHANGE, txtChange);
        this.removeEventListener(Event.REMOVED_FROM_STAGE, removeThis);
    }

    private function selectColorHandler(color:String,colorFrom:ColorForm):void {
        txt.text = "#" + color.slice(2, 8);
        txtChange(colorFrom);

        callHandler(color);
    }

    /**
     * 最近一次选中的方块
     */
    private var latestColorForm:ColorForm;

    private function txtChange(event:Object = null):void {
        var txtValue:String = txt.text;
        var txtColor:String = "";
        if (txtValue.slice(0, 1) == "#") {
            txt.maxChars = 7;
            txtColor = "0x" + txtValue.slice(1, 7);
        }else {
            txt.maxChars = 6;
            txtColor = "0x" + txtValue.slice(0, 6);
        }
        callHandler(txtColor);
		if (latestColorForm) latestColorForm.select = false;
		
		var colorForm:ColorForm =event as ColorForm
        if (colorForm) {
			colorForm.select = true;
			latestColorForm=colorForm
			return
			}
    }

    /**
     * 颜色改变时调用此函数
     * @param    color
     */
    private function callHandler(color:String):void {
        if (Boolean(theHandler)) {
            theHandler(color);
        }
    }
}
